<?php
// +----------------------------------------------------------------------
// | ManniuRead
// +----------------------------------------------------------------------
// | Copyright (c) 2006~2016 http://manniuyun.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: heitao <read@manniuyun.com>
// +----------------------------------------------------------------------

namespace app\book\model;

use manniu\model\Base;

use think\Config;
use think\Request;
use think\Db;
use manniu\controller\Cache;
use app\book\model\BookCategory;
use app\book\model\Chapter;


class Book extends Base
{
    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = true;
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    // 总字数、总点击数 - 数据自动完成
    protected $insert = ['sum_words' => 0, 'sum_click' => 0];

    // 图书缓存名
    protected $bookCacheKey = 'book{id}';
    // 图书缓存redis类型
    protected $bookRedisType = 'hash';
    // 图书缓存过期时间
    protected $bookCacheTime = 300;

    // 模型事件
    protected static function init()
    {
        // 钩子 - 新增后
        Book::afterInsert(function ($book) {
            // 生成图书url
            $book->url = str_replace(Request::instance()->baseFile(), '', url('book/book/bookinfo', ['bid' => $book->id]));
            Db::name('book')->update(['id' => $book->id, 'url' => str_replace(Request::instance()->baseFile(), '', url('book/Book/bookinfo', ['bid' => $book->id]))]);
        });

        // 钩子 - 更新前
        Book::beforeUpdate(function ($book) {
            $book->rmBookCache($book->getdata('id'));
        });

        // 钩子 - 写入后
        Book::afterWrite(function ($book) {
            $book->setBookCache($book->getdata('id'));
        });

        // 钩子 - 删除前
        Book::beforeDelete(function ($book) {
            $book->rmBookCache($book->getdata('id'));
        });
    }

    public static function search($params)
    {
        // 默认查询条件
        $where['status'] = 1;
        // 获得图书状态查询参数
        if(isset($params['action'])){
            if ($params['action'] === 'N') {
                $where['full_flag'] = 0;
            } elseif ($params['action'] === 'Y') {
                $where['full_flag'] = 1;
            }
        }
        // 获得图书VIP标识查询参数
        if(isset($params['vip'])){
            if ($params['vip'] === 'N') {
                $where['isvip'] = 0;
            } elseif ($params['vip'] === 'Y') {
                $where['isvip'] = 1;
            }
        }
        // 获得字数范围标识查询参数
        if(isset($params['size'])){
            $params['size'] = (int)$params['size'];
            $params['size'] = $params['size']>=0 && $params['size']<=5 ? $params['size'] : 0;
            switch ($params['size']) {
                case 0:
                    break;
                case 1:
                    $where['sum_words'] = ['<', 300000];
                    break;
                case 2:
                    $where['sum_words'] = ['between', [300000, 500000]];
                    break;
                case 3:
                    $where['sum_words'] = ['between', [500000, 1000000]];
                    break;
                case 4:
                    $where['sum_words'] = ['between', [1000000, 2000000]];
                    break;
                case 5:
                    $where['sum_words'] = ['>', 2000000];
                    break;
                default:
                    break;
            }
        }
        // 获得栏目id查询参数
        if(isset($params['catid'])){
            $params['catid'] = (int)$params['catid'];
            $params['catid'] = $params['catid']>=0 ? $params['catid'] : 0;
            $categorys = BookCategory::getCategoryAll();
            if (isset($categorys[$params['catid']])) {
                $where['catid'] = $params['catid'];
            }
        }
        // 获取搜索缓存时间
        $cache = Config::get('mn_book.all_searh_cache_time');
        // 查询数据
        if (config('app_debug')) {
            $cache = false;
        }
        // 查询数据
        $data = self::field('catid,name,author,cover,intro,url,full_flag,sum_words')
            ->where($where)
            ->order('id desc')
            ->cache($cache)
            ->paginate(Config::get('mn_book.all_pagesize'));

        return $data;
    }

    // 一对一关联图书附表
    public function bookData()
    {
        return $this->hasOne('BookData', 'book_id', 'id');
    }

    // 图书分卷 - 修改器
    public function setVolumesAttr($value)
    {
        if (empty(mn_array2string($value))) {
            return 0;
        } else {
            return mn_array2string($value);
        }
    }

    // 图书分卷 - 获取器
    public function getVolumesAttr($value)
    {
        $volumes = mn_string2array($value);
        if (!$volumes) {
            $volumes = 0;
        }
        return $volumes;
    }

    // 栏目名称 - 获取器
    public function getCatidAttr($value)
    {
        $catname = '暂无分类';
        $value = (int)$value;
        if (!$value) {
            return $catname;
        }
        $categorys = BookCategory::getCategoryAll();
        if (isset($categorys[$value])) {
            $catname = $categorys[$value]['name'];
        }
        return $catname;
    }

    // 完本状态 - 获取器
    public function getFullFlagAttr($value)
    {
        $full_flag = [0 => '连载中', 1 => '完本'];
        return $full_flag[$value];
    }

    // 总字数 - 获取器
    public function getSumWordsAttr($value)
    {
        return sprintf('%.2f', $value / 10000);
    }

    /**
     * 获取图书数据
     * @param int $id 图书id
     * @param int $cache sql查询缓存标识/缓存时间
     * @return array|bool|null
     */
    public function getBook($id = 0, $cache = 60)
    {
        $id = (int)$id;
        if (!$id) {
            return false;
        }
        $book = $this->getBookCache($id);
        if (!$book) {
            $book = $this->setBookCache($id, $cache, true);
        }
        return $book;
    }

    // 统计图书总字数
    public function countSumWorks($id = 0)
    {
        $id = (int)$id;
        $book = $this->where('id', $id)->find();
        if ($id && $book) {
            $book->data('sum_words', Chapter::where('book_id', $id)->sum('words'));
            $book->save();
        }
    }

    // 检查分卷信息
    public function checkVolume($data = '')
    {
        $volumes = [];
        $data = explode("\r\n", trim($data, '|'));
        // 过滤空值
        foreach ($data as $key => $value) {
            if (empty($value)) {
                unset($data[$key]);
                continue;
            }
        }
        // 验证值是否为空
        if (empty($data)) {
            return 0;
        }
        // 分析分卷信息
        foreach ($data as $key => $value) {
            $volume_param = array_values(explode('|', trim($value, '|')));
            if ((isset($volume_param[0]) && empty($volume_param[0])) || ($volume_param[0]) <= 0) {
                $this->error = '分卷排序不能为空或小于等于0';
                return false;
            }
            if (isset($volume_param[1])) {
                $volume_param[1] = str_replace(' ', '', $volume_param[1]);
                if (!is_numeric($volume_param[1]) && empty($volume_param[1])) {
                    $this->error = '分卷名称不能为空';
                    return false;
                } else {
                    $volumes[(int)$volume_param[0]] = $volume_param[1];
                }
            } else {
                $this->error = '分卷排序或分卷名称不能为空';
                return false;
            }
        }
        ksort($volumes);
        return $volumes;
    }

    /**
     * 获取图书缓存
     * @param $id 图书id
     */
    protected function getBookCache($id)
    {
        return Cache::get($this->formatCacheKey($this->bookCacheKey, ['id' => $id]), $this->bookRedisType);
    }

    /**
     * 生成图书缓存
     * @param int $id 图书id
     * @param bool $cache 缓存/缓存时间
     * @param bool $is_return 是否返回查询数据
     * @param array $hidden_field 隐藏属性
     * @return array
     */
    protected function setBookCache($id, $cache = false, $is_return = false, $hidden_field = ['update_time'])
    {
        $book = [];
        $data = $this->where(['id' => $id])->cache($cache)->find();
        if ($data) {
            $book = $data->hidden($hidden_field)->toArray();
            Cache::set($this->formatCacheKey($this->bookCacheKey, ['id' => $id]), $book, $this->bookCacheTime, $this->bookRedisType);
        }
        if ($is_return === true) {
            return $book ? $book : false;
        }
    }

    /**
     * 删除图书缓存
     * @param $id 图书id
     */
    protected function rmBookCache($id)
    {
        Cache::rm($this->formatCacheKey($this->bookCacheKey, ['id' => $id]));
    }
}